use log::{Log, Metadata, Record};
use std::sync::mpsc;
use chrono::{DateTime, Local};

#[derive(Debug, Clone)]
pub struct LogEntry {
    pub timestamp: DateTime<Local>,
    pub level: String,
    pub module: Option<String>,
    pub message: String,
}

impl LogEntry {
    pub fn new(record: &Record) -> Self {
        Self {
            timestamp: Local::now(),
            level: record.level().to_string(),
            module: record.module_path().map(|s| s.to_string()),
            message: record.args().to_string(),
        }
    }

    pub fn format_simple(&self) -> String {
        format!(
            "[{}] {} {}",
            self.timestamp.format("%H:%M:%S"),
            self.level,
            self.message
        )
    }

    pub fn format_detailed(&self) -> String {
        let module_part = if let Some(ref module) = self.module {
            format!(" [{}]", module)
        } else {
            String::new()
        };

        format!(
            "[{}] {}{} - {}",
            self.timestamp.format("%Y-%m-%d %H:%M:%S%.3f"),
            self.level,
            module_part,
            self.message
        )
    }
}

pub struct AppLogger {
    log_sender: mpsc::Sender<LogEntry>,
}

impl AppLogger {
    pub fn new(log_sender: mpsc::Sender<LogEntry>) -> Self {
        AppLogger { log_sender }
    }
}

impl Log for AppLogger {
    fn enabled(&self, metadata: &Metadata) -> bool {
        metadata.level() <= log::max_level()
    }

    fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            let entry = LogEntry::new(record);
            let _ = self.log_sender.send(entry);
        }
    }

    fn flush(&self) {}
}

// 初始化日志系统并返回接收器
pub fn init_app_logger() -> anyhow::Result<mpsc::Receiver<LogEntry>> {
    let (sender, receiver) = mpsc::channel();
    let logger = AppLogger::new(sender);

    log::set_boxed_logger(Box::new(logger))?;
    log::set_max_level(log::LevelFilter::Debug);

    Ok(receiver)
}

// 简化的日志初始化，现在由应用程序直接处理日志消息
pub fn init_simple_logger() -> anyhow::Result<()> {
    env_logger::try_init()?;
    Ok(())
}
